import { Equal, Expect } from "@type-challenges/utils";
// type RequiredByKeys<T, K = keyof T> = Omit<
//   T & Required<Pick<T, K & keyof T>>,
//   never
// >;

type RequiredByKeys<T, K = keyof T> = {
  [key in keyof T as key extends K ? key : never]-?: T[key];
} & { [key in keyof T as key extends K ? never : key]: T[key] } extends infer A
  ? { [key in keyof A]: A[key] }
  : never;

interface User {
  name?: string;
  age?: number;
  address?: string;
}

// let m: RequiredByKeys<User, "name"> = {} as any;

// type M = User & { name: string };
// let l: M = {} as any;

interface UserRequiredName {
  name: string;
  age?: number;
  address?: string;
}

interface UserRequiredNameAndAge {
  name: string;
  age: number;
  address?: string;
}

type cases = [
  Expect<Equal<RequiredByKeys<User, "name">, UserRequiredName>>,
  Expect<Equal<RequiredByKeys<User, "name" | "unknown">, UserRequiredName>>,
  Expect<Equal<RequiredByKeys<User, "name" | "age">, UserRequiredNameAndAge>>,
  Expect<Equal<RequiredByKeys<User>, Required<User>>>
];
